package www.rlicker.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class MybatisGenerator {
	private static Pattern linePattern = Pattern.compile("_(\\w)");
    private final String type_str = "VARCHAR";
    private final String type_date = "DATE";
    private final String type_decimal = "NUMBER";
    private final String types_decimal = "DECIMAL";
    private final String type_float = "FLOAT";
    private final String type_int = "INT";
    private final String type_text = "TEXT";
 
    private final String moduleName = "t_agent_user"; 
    private final String bean_package = "www.rlicker.model"; 
    private final String mapper_package = "www.rlicker.service"; 
    private final String repository_package = "www.rlicker.dao"; 
    private final String service_package_impl = "www.rlicker.service.impl";
    
    
    private static String fileName = "MybatisGenerator";
    private final static String BASE_PATH = "D:/"+fileName+"/";
    private final static String OPEN_PATH = "D:\\"+fileName;
    private final String bean_path = BASE_PATH + "model";
    private final String mapper_path = BASE_PATH + "service";
    private final String mapper_impl_path = BASE_PATH + "service/"+ "impl";
    private final String repository_path = BASE_PATH + "dao";
    private final String xml_path = BASE_PATH + "mapper";
    
   
    private final String driverName = "com.mysql.jdbc.Driver";
    private final String url = "jdbc:mysql://39.108.81.229:3306/rlicker_app";
    private final String user = "shanda";
    private final String password = "Shanda2018!";
    
    private String tableName = null;
    private String beanName = null;
    private String mapperName = null;
    private Connection conn = null;
 
 
    private void init() throws ClassNotFoundException, SQLException {
        Class.forName(driverName);
        conn = DriverManager.getConnection(url, user, password);
    }
 
 
    /**
     *
     * @return
     * @throws SQLException 
     */
    private List<String> getTables() throws SQLException {
        List<String> tables = new ArrayList<String>();
        PreparedStatement pstate = null;
        if(!StringUtil.isNullOrBlank(moduleName)){
            pstate = conn.prepareStatement("select table_name from information_schema.tables where table_name ='"+moduleName+"'");
        }else{
            pstate = conn.prepareStatement("select table_name from information_schema.tables");
        }
        ResultSet results = pstate.executeQuery();
        while ( results.next() ) {
            String tableName = results.getString(1);
            tables.add(tableName);
        }
        return tables;
    }
 
 
    private void processTable( String table ) {
        StringBuffer sb = new StringBuffer(table.length());
        String tableNew = table.toLowerCase();
        String[] tables = tableNew.split("_");
        String temp = null;
        if(tables.length>1){
            for ( int i = 0 ; i < tables.length ; i++ ) {
                temp = tables[i].trim();
                sb.append(temp.substring(0, 1).toUpperCase()).append(temp.substring(1));
            }
        }else{
            sb.append(tableNew.substring(0, 1).toUpperCase()).append(tableNew.substring(1));
        }
        
        beanName = sb.substring(1); 
        mapperName = beanName;
    }
 
 
    private String processType(String type) {
    	type = type.toUpperCase();
        if ( type.indexOf(type_str) > -1 ) {
            return "String";
        }else if ( type.indexOf(type_date) > -1 ) {
            return "Date";
        }else if ( type.indexOf(type_decimal) > -1 || type.indexOf(types_decimal) > -1) {
            return "BigDecimal";
        }else if ( type.indexOf(type_float) > -1 ) {
            return "Float";
        }else if ( type.indexOf(type_int) > -1 ) {
            return "Integer";
        }else if ( type.indexOf(type_text) > -1 ) {
            return "String";
        }
        
        return null;
    }
 
    private String processTypeToMysql(String type){
    	type = type.toUpperCase();
    	if(type.indexOf(type_date) > -1){
    		return "TIMESTAMP";
    	}else if(type.indexOf(type_int) > -1){
    		return "INTEGER";
    	}else if(type.indexOf(type_float) > -1){
        	return "FLOAT";
    	}else if (type.indexOf(types_decimal) > -1) {
    		return "DECIMAL";
		}else{
    		return "VARCHAR";
    	}
    }
    private String processField( String field ) {
        StringBuffer sb = new StringBuffer(field.length());
        String[] fields = field.split("_");
        String temp = null;
        sb.append(fields[0]);
        if(fields.length>1){
            for ( int i = 1 ; i < fields.length ; i++ ) {
                temp = fields[i].trim();
                sb.append(temp.substring(0, 1).toUpperCase()).append(temp.substring(1));
            }
        }
        return sb.toString();
    }
 
 
    /**
     *
     * @param beanName
     * @return 
     */
    private String processResultMapId( String beanName ) {
    	return bean_package+"."+beanName;
    }
 
    /**
     *
     * @param bw
     * @param text
     * @return
     * @throws IOException 
     */
    private BufferedWriter buildClassComment( BufferedWriter bw, String text ) throws IOException {
        bw.newLine();
        bw.newLine();
        bw.write("/**");
        bw.newLine();
        bw.write(" * ");
        bw.newLine();
        bw.write(" * " + text);
        bw.newLine();
        bw.write(" * ");
        bw.newLine();
        bw.write(" **/");
        return bw;
    }
 
 
    /**
     *
     * @param bw
     * @param text
     * @return
     * @throws IOException 
     */
    private BufferedWriter buildMethodComment( BufferedWriter bw, String text ) throws IOException {
        bw.newLine();
        bw.write("\t/**");
        bw.newLine();
        bw.write("\t * ");
        bw.newLine();
        bw.write("\t * " + text);
        bw.newLine();
        bw.write("\t * ");
        bw.newLine();
        bw.write("\t **/");
        return bw;
    }
 
 
    /**
     *  閻㈢喐鍨氱�圭偘缍嬬猾锟�
     *
     * @param columns
     * @param types
     * @param comments
     * @throws IOException 
     */
    private void buildEntityBean( List<String> columns, List<String> types, List<String> comments, String tableComment )
        throws IOException {
        File folder = new File(bean_path);
        if ( !folder.exists() ) {
            folder.mkdir();
        }
 
        File beanFile = new File(bean_path, beanName + ".java");
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(beanFile)));
        bw.write("package " + bean_package + ";");
        bw.newLine();
        bw.write("import java.io.Serializable;");
        bw.newLine();
        bw.write("import www.rlicker.mybatis.IModel;");
        bw.newLine();
        bw.write("import java.math.BigDecimal;");
        bw.newLine();
        bw.write("import java.util.Date;");
        bw.newLine();
        bw = buildClassComment(bw, tableComment);
        bw.newLine();
        bw.write("public class " + beanName + " implements IModel{");
        bw.newLine();
        bw.newLine();
        int size = columns.size();
        for ( int i = 0 ; i < size ; i++ ) {
            bw.write("\t/**" + comments.get(i) + "**/");
            bw.newLine();
            bw.write("\tprivate " + processType(types.get(i)) + " " + processField(columns.get(i)) + ";");
            bw.newLine();
            bw.newLine();
        }
        bw.newLine();
        String tempField = null;
        String _tempField = null;
        String tempType = null;
        for ( int i = 0 ; i < size ; i++ ) {
            tempType = processType(types.get(i));
            _tempField = processField(columns.get(i));
            tempField = _tempField.substring(0, 1).toUpperCase() + _tempField.substring(1);
            bw.newLine();
            bw.write("\tpublic void set" + tempField + "(" + tempType + " " + _tempField + "){");
            bw.newLine();
            bw.write("\t\tthis." + _tempField + " = " + _tempField + ";");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();
            bw.write("\tpublic " + tempType + " get" + tempField + "(){");
            bw.newLine();
            bw.write("\t\treturn this." + _tempField + ";");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
        }
        bw.newLine();
        bw.write("}");
        bw.newLine();
        bw.flush();
        bw.close();
    }
 
 
    /**
     *  閺嬪嫬缂搒ervice閺傚洣娆�
     *
     * @throws IOException 
     */
    private void buildMapper(List<String> columns, List<String> types) throws IOException {
        File folder = new File(mapper_path);
        if ( !folder.exists() ) {
            folder.mkdirs();
        }
 
        File mapperFile = new File(mapper_path, "I"+mapperName + "Service.java");
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(mapperFile), "utf-8"));
        bw.write("package " + mapper_package + ";");
        bw.newLine();
        bw.newLine();
        bw.write("import " + bean_package + "." + beanName + ";");
        bw.newLine();
        bw.write("import java.util.Map;");
        bw.newLine();
        bw.write("import www.rlicker.mybatis.Criteria;");
        bw.newLine();
        bw.write("import java.util.List;");
        bw = buildClassComment(bw, mapperName + "鏁版嵁搴撴搷浣滄帴鍙ｇ被");
        bw.newLine();
        bw.newLine();
        bw.write("public interface I" + mapperName + "Service{");
        bw.newLine();
        bw.newLine();
        String pkType = processType(types.get(0));
        bw = buildMethodComment(bw, "鍒嗛〉鏌ヨ");
        bw.newLine();
        bw.write("\tpublic List<Map<String, Object>>  queryPage (Criteria<" + beanName + "> param);");
        bw.newLine();
        bw = buildMethodComment(bw, "鍒嗛〉鎬绘暟鏌ヨ");
        bw.newLine();
        bw.write("\tpublic Integer queryPageCount (Criteria<" + beanName + "> param);");
        bw.newLine();
        bw = buildMethodComment(bw, "鏌ヨ锛堟牴鎹富閿甀D鏌ヨ锛�");
        bw.newLine();
        bw.write("\tpublic " + beanName + "  queryEntity ("+pkType+" "+"id"+" );");
        bw.newLine();
        bw = buildMethodComment(bw, "鍒犻櫎锛堟牴鎹富閿甀D鍒犻櫎锛�");
        bw.newLine();
        bw.write("\tpublic " + "String delete"+"ById ("+pkType+" "+"id"+" );");
        bw.newLine();
        bw = buildMethodComment(bw, "娣诲姞 锛堝尮閰嶆湁鍊肩殑瀛楁锛�");
        bw.newLine();
        bw.write("\tpublic " + "String insert"+"(" + beanName + " record );");
        bw = buildMethodComment(bw, "淇敼锛堝尮閰嶆湁鍊肩殑瀛楁锛�");
        bw.newLine();
        bw.write("\tpublic " + "String update"+" (Criteria<" + beanName + "> param);");
        bw.newLine();
        bw.newLine();
        bw.write("}");
        bw.flush();
        bw.close();
    }
    /**
     *  閺嬪嫬缂搒erviceImpl閺傚洣娆�
     *
     * @throws IOException 
     */
    private void buildimplMapper(List<String> columns, List<String> types) throws IOException {
    	File folder = new File(mapper_impl_path);
    	if ( !folder.exists() ) {
    		folder.mkdirs();
    	}
    	
    	File mapperFile = new File(mapper_impl_path, mapperName + "ServiceImpl.java");
    	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(mapperFile), "utf-8"));
    	String str = beanName.substring(0, 1);
    	String name = beanName.replaceFirst(str, str.toLowerCase())+"Repository";
    	bw.write("package " + service_package_impl + ";");
    	bw.newLine();
    	bw.newLine();
    	bw.write("import " + bean_package + "." + beanName + ";");
    	bw.newLine();
    	bw.write("import java.util.Map;");
    	bw.newLine();
    	bw.write("import javax.annotation.Resource;");
    	bw.newLine();
    	bw.write("import www.rlicker.dao.I"+ beanName +"Dao;");
    	bw.newLine();
    	bw.write("import org.springframework.stereotype.Service;");
    	bw.newLine();
    	bw.write("import www.rlicker.mybatis.Criteria;");
    	bw.newLine();
    	bw.write("import www.rlicker.service.I"+ beanName +"Service;");
    	bw.newLine();
    	bw.write("import www.rlicker.utils.TranslateToMap;");
    	bw.newLine();
    	bw.write("import java.util.List;");
    	bw = buildClassComment(bw, mapperName + "鏁版嵁搴撴搷浣滄帴鍙ｇ被");
    	bw.newLine();
    	bw.newLine();
    	bw.write("@Service");
    	bw.newLine();
    	bw.write("public class " + mapperName + "ServiceImpl implements I"+ beanName +"Service{");
    	bw.newLine();
    	bw.newLine();
    	String pkType = processType(types.get(0));
    	bw = buildMethodComment(bw, "鍒嗛〉鏌ヨ");
    	bw.newLine();
    	bw.write("\tpublic List<Map<String, Object>>  queryPage (Criteria<" + beanName + "> param){");
    	bw.newLine();
    	bw.write("\t\tList<"+ beanName +"> list = "+ name +".queryPage(param);");
    	bw.newLine();
    	bw.write("\t\t\tList<Map<String,Object>> map = TranslateToMap.convertListBean2ListMap(list,"+beanName+".class);");
    	bw.newLine();
    	bw.write("\treturn map;  }");
    	bw.newLine();
    	bw = buildMethodComment(bw, "鍒嗛〉鎬绘暟鏌ヨ");
    	bw.newLine();
    	bw.write("\tpublic Integer queryPageCount (Criteria<" + beanName + "> param){");
    	bw.newLine();
    	bw.write("\t\treturn (Integer) "+ name +".queryPageCount(param);");
    	bw.newLine();
    	bw.write("\t}");
    	bw.newLine();
    	bw = buildMethodComment(bw, "鏌ヨ锛堟牴鎹富閿甀D鏌ヨ锛�");
    	bw.newLine();
    	bw.write("\tpublic " + beanName + "  queryEntity ("+pkType+" "+"id"+" ){");
    	bw.newLine();
    	bw.write("\t\treturn "+ name +".queryEntity(id);");
    	bw.newLine();
    	bw.write("\t}");
    	bw.newLine();
    	bw = buildMethodComment(bw, "鍒犻櫎锛堟牴鎹富閿甀D鍒犻櫎锛�");
    	bw.newLine();
    	bw.write("\tpublic " + "String delete"+"ById ("+pkType+" "+"id"+" ){");
    	bw.newLine();
    	bw.write("\t\tint result = "+ name +".deleteById(id);");
    	bw.newLine();
    	bw.write("\t\t\tif ( result != 1) {");
    	bw.newLine();
    	bw.write("\t\t\t\t\treturn null;");
    	bw.newLine();
    	bw.write("\t\t\t}");
    	bw.newLine();
    	bw.write("\t\t\treturn null;");
    	bw.newLine();
    	bw.write("\t}");
    	bw.newLine();
    	bw = buildMethodComment(bw, "娣诲姞 锛堝尮閰嶆湁鍊肩殑瀛楁锛�");
    	bw.newLine();
    	bw.write("\tpublic " + "String insert"+"(" + beanName + " record ){");
    	bw.newLine();
    	bw.write("\t\tint result = "+ name +".insert(record);");
    	bw.newLine();
    	bw.write("\t\t\tif ( result != 1) { ");
    	bw.newLine();
    	bw.write("\t\t\t\t\treturn null;");
    	bw.newLine();
    	bw.write("\t\t\t}");
    	bw.newLine();
    	bw.write("\t\t\treturn null;");
    	bw.newLine();
    	bw.write("\t}");
    	bw.newLine();
    	bw = buildMethodComment(bw, "淇敼锛堝尮閰嶆湁鍊肩殑瀛楁锛�");
    	bw.newLine();
    	bw.write("\tpublic " + "String update"+" (Criteria<" + beanName + "> param){");
    	bw.newLine();
     	bw.write("\t\tint result = "+ name +".update(param);");
    	bw.newLine();
    	bw.write("\t\t\tif ( result != 1) { ");
    	bw.newLine();
    	bw.write("\t\t\t\t\treturn null;");
    	bw.newLine();
    	bw.write("\t\t\t}");
    	bw.newLine();
    	bw.write("\t\t\treturn null;");
    	bw.newLine();
    	bw.write("\t}");
    	bw.newLine();
    	bw.newLine();
    	bw.write("\t@Resource");
    	bw.newLine();
    	bw.write("\tprivate I"+ beanName + "Dao "+ name+";");
    	bw.newLine();

    	bw.newLine();
    	bw.write("}");
    	bw.flush();
    	bw.close();
    }
 
    
    /**
     *
     * @throws IOException 
     */
    private void repositoryMapper(List<String> columns, List<String> types) throws IOException {
    	File folder = new File(repository_path);
    	if ( !folder.exists() ) {
    		folder.mkdirs();
    	}
    	
    	File mapperFile = new File(repository_path, "I"+mapperName + "Dao.java");
    	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(mapperFile), "utf-8"));
    	bw.write("package " + repository_package + ";");
    	bw.newLine();
    	bw.newLine();
    	bw.write("import " + bean_package + "." + beanName + ";");
    	bw.newLine();
    	bw.write("import www.rlicker.mybatis.Criteria;");
    	bw.newLine();
    	bw.write("import java.util.List;");
    	bw = buildClassComment(bw, mapperName + "鏁版嵁搴撴搷浣滄帴鍙ｇ被");
    	bw.newLine();
    	bw.newLine();
    	bw.write("public interface I" + mapperName + "Dao{");
    	bw.newLine();
    	bw.newLine();
    	String pkType = processType(types.get(0));
    	bw = buildMethodComment(bw, "鍒嗛〉鏌ヨ");
    	bw.newLine();
    	bw.write("\tpublic List<" + beanName + ">  queryPage (Criteria<" + beanName + "> param);");
    	bw.newLine();
    	bw = buildMethodComment(bw, "鍒嗛〉鎬绘暟鏌ヨ");
    	bw.newLine();
    	bw.write("\tpublic Integer queryPageCount (Criteria<" + beanName + "> param);");
    	bw.newLine();
    	bw = buildMethodComment(bw, "鏌ヨ锛堟牴鎹富閿甀D鏌ヨ锛�");
    	bw.newLine();
    	bw.write("\tpublic " + beanName + "  queryEntity ("+pkType+" "+"id"+" );");
    	bw.newLine();
    	bw = buildMethodComment(bw, "鍒犻櫎锛堟牴鎹富閿甀D鍒犻櫎锛�");
    	bw.newLine();
    	bw.write("\tpublic " + "int delete"+"ById ("+pkType+" "+"id"+" );");
    	bw.newLine();
    	bw = buildMethodComment(bw, "娣诲姞 锛堝尮閰嶆湁鍊肩殑瀛楁锛�");
    	bw.newLine();
    	bw.write("\tpublic " + "int insert"+"(" + beanName + " record );");
    	bw = buildMethodComment(bw, "淇敼锛堝尮閰嶆湁鍊肩殑瀛楁锛�");
    	bw.newLine();
    	bw.write("\tpublic " + "int update"+" (Criteria<" + beanName + "> param);");
    	bw.newLine();
    	bw.newLine();
    	bw.newLine();
    	bw.write("}");
    	bw.flush();
    	bw.close();
    }     
 
    /**
     *
     * @param columns
     * @param types
     * @param comments
     * @throws IOException 
     */
  
    private void buildMapperXml( List<String> columns, List<String> types, List<String> comments ) throws IOException {
        File folder = new File(xml_path);
        if ( !folder.exists() ) {
            folder.mkdirs();
        }
 
        File mapperXmlFile = new File(xml_path, beanName+ "Mapper.xml");
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(mapperXmlFile)));
        bw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        bw.newLine();
        bw.write("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">");
        bw.newLine();
        bw.write("<mapper namespace=\"" + repository_package + ".I" + mapperName + "Dao\">");
        bw.newLine();
        bw.newLine();

        buildSQL(bw, columns, types);
 
        bw.write("</mapper>");
        bw.flush();
        bw.close();
    }
 
 
    private void buildSQL( BufferedWriter bw, List<String> columns, List<String> types ) throws IOException {
        int size = columns.size();
        // 闁氨鏁esultMap
        bw.write("\t<!-- 闁氨鏁esultMap-->");
        bw.newLine();
        bw.write("\t<resultMap type=\""+processResultMapId(beanName)+"\" id=\"BaseResultMap\">");
        bw.newLine();
 
        for ( int i = 0 ; i < size ; i++ ) {
        	
        	if("ID".equals(columns.get(i).toUpperCase())){
        		bw.write("\t\t<id property=\""+lineToHump(columns.get(i))+"\" column=\""+columns.get(i)+"\" jdbcType=\""+processTypeToMysql(types.get(i))+"\" />");
        		bw.newLine();
        	}else{
        		bw.write("\t\t<result property=\""+lineToHump(columns.get(i))+"\" column=\""+columns.get(i)+"\" jdbcType=\""+processTypeToMysql(types.get(i))+"\" />");
        		bw.newLine();
        	}
        }
 
        bw.write("\t</resultMap>");
        bw.newLine();
        bw.newLine();
        
        // 闁氨鏁esultMap
        bw.write("\t<!-- 閫氱敤鏉′欢鏌ヨ-->");
        bw.newLine();
        bw.write("\t<sql id=\"Criteria_Where_Clause\">");
        bw.newLine();
        bw.write(" \t\t <where> ");
        bw.newLine();
        bw.write(" \t\t\t 1=1 ");
        bw.newLine();
        String tempCond="params.";
        for ( int i = 0 ; i < size ; i++ ) {
            bw.write("\t\t\t<if test=\"" + tempCond+columns.get(i) + " != null\">");
            bw.newLine();
            bw.write("\t\t\t\t and " + columns.get(i) + " = #{" + tempCond+columns.get(i) + ",jdbcType=VARCHAR}");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
 
        bw.newLine();
        bw.write(" \t\t </where>");
        bw.newLine();
        bw.write("\t</sql>");
        bw.newLine();
        bw.newLine();
        
        bw.write("\t<!-- 閫氱敤鏌ヨ缁撴灉鍒�-->");
        bw.newLine();
        bw.write("\t<sql id=\"Base_Column_List\">");
        bw.newLine();
 
        for ( int i = 0 ; i < size ; i++ ) {
            bw.write("\t"+columns.get(i));
            if ( i != size - 1 ) {
                bw.write(",");
            }
        }
 
        bw.newLine();
        bw.write("\t</sql>");
        bw.newLine();
        bw.newLine();
 

        bw.write("\t<!-- 闆嗗悎锛堝尮閰嶆湁鍊肩殑瀛楁锛�-->");
        bw.newLine();
        bw.write("\t<select id=\"queryPage\" parameterType=\"www.rlicker.mybatis.Criteria\" resultMap=\"BaseResultMap\" >");
        bw.newLine();
        bw.write("\t\t SELECT");
        bw.newLine();
        bw.write("\t\t <include refid=\"Base_Column_List\" />");
        bw.newLine();
        bw.write("\t\t FROM " + tableName);
        bw.newLine();
        bw.write("\t\t <if test=\"params != null\">");
        bw.newLine();
        bw.write("\t\t\t <include refid=\"Criteria_Where_Clause\" />");
        bw.newLine();
        bw.write("\t\t </if>");
        bw.newLine();
        bw.write("\t</select>");
        bw.newLine();
        bw.newLine();
        
        bw.write("\t<!-- 缁熻锛堝尮閰嶆湁鍊肩殑瀛楁锛�-->");
        bw.newLine();
        bw.write("\t<select id=\"queryPageCount\" parameterType=\"www.rlicker.mybatis.Criteria\" resultType=\"java.lang.Integer\" >");
        bw.newLine();
        bw.write("\t\t SELECT");
        bw.newLine();
        bw.write("\t\t COUNT(1)");
        bw.newLine();
        bw.write("\t\t FROM " + tableName);
        bw.newLine();
        bw.write("\t\t <if test=\"params != null\">");
        bw.newLine();
        bw.write("\t\t\t <include refid=\"Criteria_Where_Clause\" />");
        bw.newLine();
        bw.write("\t\t </if>");
        bw.newLine();
        bw.write("\t</select>");
        bw.newLine();
        bw.newLine();
        
        // 閺屻儴顕楅敍鍫熺壌閹诡喕瀵岄柨鐢�D閺屻儴顕楅敍锟�
        bw.write("\t<!-- 鏌ヨ锛堟牴鎹富閿甀D鏌ヨ锛� -->");
        bw.newLine();
        bw.write("\t<select id=\"queryEntity\" parameterType=\"java.lang.String\" resultMap=\"BaseResultMap\">");
        bw.newLine();
        bw.write("\t\t SELECT");
        bw.newLine();
        bw.write("\t\t <include refid=\"Base_Column_List\" />");
        bw.newLine();
        bw.write("\t\t FROM " + tableName);
        bw.newLine();
        bw.write("\t\t WHERE " + columns.get(0) + " = #{" + processField(columns.get(0)) + "}");
        bw.newLine();
        bw.write("\t</select>");
        bw.newLine();
        bw.newLine();
 
 
        bw.write("\t<!--鍒犻櫎锛氭牴鎹富閿甀D鍒犻櫎-->");
        bw.newLine();
        bw.write("\t<delete id=\"deleteById\" parameterType=\"java.lang.String\">");
        bw.newLine();
        bw.write("\t\t DELETE FROM " + tableName);
        bw.newLine();
        bw.write("\t\t WHERE " + columns.get(0) + " = #{" + processField(columns.get(0)) + "}");
        bw.newLine();
        bw.write("\t</delete>");
        bw.newLine();
        bw.newLine();
 
        bw.write("\t<!-- 娣诲姞 锛堝尮閰嶆湁鍊肩殑瀛楁锛�-->");
        bw.newLine();
        bw.write("\t<insert id=\"insert\" parameterType=\"" + processResultMapId(beanName) + "\">");
        bw.newLine();
        bw.write("\t\t INSERT INTO " + tableName);
        bw.newLine();
        bw.write("\t\t <trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\" >");
        bw.newLine();
 
        String tempField = null;
        for ( int i = 0 ; i < size ; i++ ) {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"" + tempField + " != null\">");
            bw.newLine();
            bw.write("\t\t\t\t " + columns.get(i) + ",");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
 
        bw.newLine();
        bw.write("\t\t </trim>");
        bw.newLine();
 
        bw.write("\t\t <trim prefix=\"values (\" suffix=\")\" suffixOverrides=\",\" >");
        bw.newLine();
 
        tempField = null;
        for ( int i = 0 ; i < size ; i++ ) {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"" + tempField + "!=null\">");
            bw.newLine();
            bw.write("\t\t\t\t #{" + tempField + "},");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
 
        bw.write("\t\t </trim>");
        bw.newLine();
        bw.write("\t</insert>");
        bw.newLine();
        bw.newLine();
        //---------------  鐎瑰本鐦�
 
 
        bw.write("\t<!-- 淇� 鏀�-->");
        bw.newLine();
        bw.write("\t<update id=\"update\" parameterType=\"www.rlicker.mybatis.Criteria\">");
        bw.newLine();
        bw.write("\t\t UPDATE " + tableName);
        bw.newLine();
        bw.write(" \t\t <set> ");
        bw.newLine();
 
        tempField = null;
        for ( int i = 1 ; i < size ; i++ ) {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"record." + tempField + " != null\">");
            bw.newLine();
            bw.write("\t\t\t\t " + columns.get(i) + " = #{record." + tempField + "},");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
 
        bw.newLine();
        bw.write(" \t\t </set>");
        bw.newLine();
        bw.write("\t\t WHERE " + columns.get(0) + " = #{" + processField(columns.get(0)) + "}");
        bw.newLine();
        bw.write("\t</update>");
        bw.newLine();
        bw.newLine();
        bw.newLine();
    }
 
 
    public void generate() throws ClassNotFoundException, SQLException, IOException {
        init();
        //String prefix = "select column_name,data_type from user_tab_columns where  table_name=";
        String prefix = "select column_name,data_type,column_comment from information_schema.columns where  table_name=";
        List<String> columns = null;
        List<String> types = null;
        List<String> comments = null;
        PreparedStatement pstate = null;
        List<String> tables = getTables();
        for ( String table : tables ) {
            columns = new ArrayList<String>();
            types = new ArrayList<String>();
            comments = new ArrayList<String>();
            pstate = conn.prepareStatement(prefix +"'"+ table +"'");
            ResultSet results = pstate.executeQuery();
            while ( results.next() ) {
                columns.add(results.getString("column_name"));
                types.add(results.getString("data_type"));
                comments.add(results.getString("column_comment"));
            }
            tableName = table;
            processTable(table);
            buildEntityBean(columns, types, comments, "鏁版嵁搴撹〃鍚嶇О:"+tableName);
            buildMapper(columns, types);
            buildimplMapper(columns, types);
            repositoryMapper(columns, types);
            buildMapperXml(columns, types, comments);
        }
        conn.close();
    }
    
    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    
    public static boolean deleteDirectory(String sPath) {
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) break;
            }
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) break;
            }
        }
        if (!flag) return false;
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }
 
    /**
     * @param args
     */
    public static void main( String[] args ) {
        try {
            File folder = new File(BASE_PATH);
            if (folder.isFile()) {  
                 deleteFile(BASE_PATH);  
            } else { 
                 deleteDirectory(BASE_PATH);  
            }  
            folder.mkdir();
            new MybatisGenerator().generate();
            Runtime.getRuntime().exec("cmd /c start explorer "+OPEN_PATH);
        } catch ( ClassNotFoundException e ) {
            e.printStackTrace();
        } catch ( SQLException e ) {
            e.printStackTrace();
        } catch ( IOException e ) {
            e.printStackTrace();
        }
    }
    
    /**
     * 
     * @param str
     * @return
     */
    private String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    
}

